﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace ArgusLib.Xml
{
	public abstract class SerializableSettings
	{
		const string XmlRootName = "Settings";
		static Dictionary<Type, SerializableSettings> initializedSettings;

		static SerializableSettings()
		{
			SerializableSettings.initializedSettings = new Dictionary<Type, SerializableSettings>();
		}

		/// <summary>
		/// Path of the file in which the settings are stored.
		/// </summary>
		protected abstract string SettingsPath { get; }

		public abstract void Reset();

		/// <summary>
		/// Default: false
		/// </summary>
		protected virtual bool SaveOnDisposing { get { return false; } }

		public static T Load<T>() where T : SerializableSettings, new()
		{
			Type type = typeof(T);

			SerializableSettings settings;
			if (SerializableSettings.initializedSettings.TryGetValue(type, out settings) == true)
				return (T)settings;

			T RetVal = new T();
			if (File.Exists(RetVal.SettingsPath) == false)
			{
				SerializableSettings.initializedSettings.Add(type, RetVal);
				return RetVal;
			}
			else
			{
				using (FileStream file = new FileStream(RetVal.SettingsPath, FileMode.Open))
				{
					using (Deserializer deserializer = Deserializer.FromStream(file))
					{
						object obj = deserializer.Deserialize();
						if (obj is T)
							RetVal = (T)obj;
					}
				}

				SerializableSettings.initializedSettings.Add(type, RetVal);
				return RetVal;
			}
		}

		public void Save()
		{
			using (FileStream file = new FileStream(this.SettingsPath, FileMode.Create))
			{
				using (Serializer serializer = Serializer.FromStream(file, SerializableSettings.XmlRootName))
				{
					serializer.Serialize(this);
				}
			}
		}

		~SerializableSettings()
		{
			if (this.SaveOnDisposing == true)
				this.Save();
		}
	}
}
